import string
import random
import os
from PIL import Image, ImageDraw, ImageFont, ImageFilter


# 写验证码组成: 包括图片、验证码、干扰线、干扰点、颜色
class VerifyUtil:
    # 构造函数,对于验证码要求
    def __init__(self, width=140, height=40, length=4, size=28):
        # 设置初始值
        self.width = width
        self.height = height
        self.length = length
        self.size = size

    # 生成对于RGB颜色
    def create_rgb(self):
        # 随机生成3位rgb颜色组
        rgb = [random.randint(0, 255) for i in range(self.length-1)]
        return tuple(rgb)

    # 生成四位数验证码
    def create_verify(self):
        # 集合所有字母以及数字
        res = string.ascii_letters + string.digits
        # 集合中随机取四个并返回
        return ''.join(random.choices(res, k=self.length))

    # 设置干扰线
    def create_line(self, draw):
        # 设置六条线
        for i in range(6):
            # 两点连线并绘制
            lines = [(random.randint(0, self.width), random.randint(0, self.height)) for i in range(2)]
            draw.line(lines, fill=self.create_rgb(), width=2)

    # 设置干扰点
    def create_point(self, draw):
        # 对每个点进行遍历,根据概率进行汇点
        for i in range(self.width):
            for j in range(self.height):
                if random.randint(0, 100) <= 10:
                    draw.point((i, j), fill=self.create_rgb())

    # 综合方法
    def create_verify_img(self):
        # 生成画布
        img = Image.new('RGB', (self.width, self.height), (255, 255, 255))
        # 获取文件位置
        file = os.path.dirname(os.path.abspath(__file__))
        font = ImageFont.truetype(f"{file}/HYYakuHei-85W.ttf", self.size)
        # 生成画笔,通过画布对象生成画笔对象
        draw = ImageDraw.Draw(img)
        # 进行绘制
        self.create_line(draw)
        self.create_point(draw)
        code = self.create_verify()
        # 验证码填入画布,并给出x轴偏移
        for i in range(self.length):
            draw.text((i*35, 5), code[i], font=font, fill=self.create_rgb())
        # 添加模糊,这里可有可无
        # img = img.filter(ImageFilter.BLUR)
        # 返回图片和验证码
        return img, code


if __name__ == '__main__':
    verify_util = VerifyUtil()
    image, code = verify_util.create_verify_img()
    with open(r'verify.png', 'wb') as f:
        image.save(f)
    print(code)
